package com.apkicon.processor;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

/**
 * Enhanced Adaptive Icon Processor - Based on ARGB rendering approach
 * Optimized to match the quality of test_argb_adaptive.png
 */
public class EnhancedAdaptiveIconProcessor {
    
    /**
     * Render Adaptive Icon with enhanced ARGB-based algorithm
     */
    public static BufferedImage renderAdaptiveIcon(BufferedImage background, BufferedImage foreground, int targetSize) {
        if (background == null || foreground == null) {
            throw new IllegalArgumentException("Background and foreground images cannot be null");
        }
        
        // Use ARGB format for better color handling and transparency support
        BufferedImage result = new BufferedImage(targetSize, targetSize, BufferedImage.TYPE_INT_ARGB);
        Graphics2D g2d = result.createGraphics();
        
        try {
            // Enhanced rendering hints for better quality
            setupHighQualityRendering(g2d);
            
            // Clear background with transparent
            g2d.setComposite(AlphaComposite.Clear);
            g2d.fillRect(0, 0, targetSize, targetSize);
            
            // Reset composite for normal drawing
            g2d.setComposite(AlphaComposite.SrcOver);
            
            // Render background layer
            renderBackgroundLayer(g2d, background, targetSize);
            
            // Render foreground layer with proper scaling
            renderForegroundLayer(g2d, foreground, targetSize);
            
        } finally {
            g2d.dispose();
        }
        
        return result;
    }
    
    /**
     * Setup high-quality rendering hints
     */
    private static void setupHighQualityRendering(Graphics2D g2d) {
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
        g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
        g2d.setRenderingHint(RenderingHints.KEY_COLOR_RENDERING, RenderingHints.VALUE_COLOR_RENDER_QUALITY);
        g2d.setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION, RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY);
        g2d.setRenderingHint(RenderingHints.KEY_DITHERING, RenderingHints.VALUE_DITHER_ENABLE);
        g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
    }
    
    /**
     * Render background layer with proper scaling and positioning
     */
    private static void renderBackgroundLayer(Graphics2D g2d, BufferedImage background, int targetSize) {
        // Background fills the entire 108dp area
        int backgroundSize = targetSize;
        
        // Scale background to fit the target size
        g2d.drawImage(background, 0, 0, backgroundSize, backgroundSize, null);
    }
    
    /**
     * Render foreground layer with proper scaling and centering
     */
    private static void renderForegroundLayer(Graphics2D g2d, BufferedImage foreground, int targetSize) {
        // Foreground is scaled to fit within the 72dp safe area
        // Calculate the safe area size (72dp out of 108dp)
        int safeAreaSize = (int) (targetSize * 72.0 / 108.0);
        int offset = (targetSize - safeAreaSize) / 2;
        
        // Draw foreground centered in the safe area
        g2d.drawImage(foreground, offset, offset, safeAreaSize, safeAreaSize, null);
    }
    
    /**
     * Process background image with enhanced color handling
     */
    public static BufferedImage processBackgroundImage(BufferedImage originalBackground) {
        if (originalBackground == null) {
            return createDefaultBackground();
        }
        
        // Convert to ARGB for better color processing
        BufferedImage processed = new BufferedImage(
            originalBackground.getWidth(), 
            originalBackground.getHeight(), 
            BufferedImage.TYPE_INT_ARGB
        );
        
        Graphics2D g2d = processed.createGraphics();
        try {
            setupHighQualityRendering(g2d);
            
            // Handle 9-patch images
            if (isNinePatchImage(originalBackground)) {
                processed = processNinePatchImage(originalBackground);
            } else {
                // Direct copy with ARGB conversion
                g2d.drawImage(originalBackground, 0, 0, null);
            }
            
        } finally {
            g2d.dispose();
        }
        
        return processed;
    }
    
    /**
     * Process foreground image with enhanced quality
     */
    public static BufferedImage processForegroundImage(BufferedImage originalForeground) {
        if (originalForeground == null) {
            return createDefaultForeground();
        }
        
        // Convert to ARGB for better color processing
        BufferedImage processed = new BufferedImage(
            originalForeground.getWidth(), 
            originalForeground.getHeight(), 
            BufferedImage.TYPE_INT_ARGB
        );
        
        Graphics2D g2d = processed.createGraphics();
        try {
            setupHighQualityRendering(g2d);
            
            // Handle 9-patch images
            if (isNinePatchImage(originalForeground)) {
                processed = processNinePatchImage(originalForeground);
            } else {
                // Direct copy with ARGB conversion
                g2d.drawImage(originalForeground, 0, 0, null);
            }
            
        } finally {
            g2d.dispose();
        }
        
        return processed;
    }
    
    /**
     * Check if image is a 9-patch image
     */
    private static boolean isNinePatchImage(BufferedImage image) {
        // Simple heuristic: check if image has 1-pixel border with specific patterns
        int width = image.getWidth();
        int height = image.getHeight();
        
        if (width < 3 || height < 3) {
            return false;
        }
        
        // Check for 9-patch markers in the border
        return hasNinePatchMarkers(image);
    }
    
    /**
     * Check for 9-patch markers in image borders
     */
    private static boolean hasNinePatchMarkers(BufferedImage image) {
        int width = image.getWidth();
        int height = image.getHeight();
        
        // Check top and left borders for black markers
        for (int x = 0; x < width; x++) {
            int topPixel = image.getRGB(x, 0);
            if (isBlackPixel(topPixel)) {
                return true;
            }
        }
        
        for (int y = 0; y < height; y++) {
            int leftPixel = image.getRGB(0, y);
            if (isBlackPixel(leftPixel)) {
                return true;
            }
        }
        
        return false;
    }
    
    /**
     * Check if pixel is black (9-patch marker)
     */
    private static boolean isBlackPixel(int rgb) {
        int alpha = (rgb >> 24) & 0xFF;
        int red = (rgb >> 16) & 0xFF;
        int green = (rgb >> 8) & 0xFF;
        int blue = rgb & 0xFF;
        
        return alpha > 0 && red == 0 && green == 0 && blue == 0;
    }
    
    /**
     * Process 9-patch image by removing the border
     */
    private static BufferedImage processNinePatchImage(BufferedImage ninePatchImage) {
        int width = ninePatchImage.getWidth();
        int height = ninePatchImage.getHeight();
        
        // Remove 1-pixel border
        BufferedImage processed = new BufferedImage(width - 2, height - 2, BufferedImage.TYPE_INT_ARGB);
        Graphics2D g2d = processed.createGraphics();
        
        try {
            setupHighQualityRendering(g2d);
            
            // Copy content area (skip border)
            g2d.drawImage(ninePatchImage, -1, -1, null);
            
        } finally {
            g2d.dispose();
        }
        
        return processed;
    }
    
    /**
     * Create default background (white)
     */
    private static BufferedImage createDefaultBackground() {
        BufferedImage background = new BufferedImage(108, 108, BufferedImage.TYPE_INT_ARGB);
        Graphics2D g2d = background.createGraphics();
        
        try {
            setupHighQualityRendering(g2d);
            g2d.setColor(Color.WHITE);
            g2d.fillRect(0, 0, 108, 108);
        } finally {
            g2d.dispose();
        }
        
        return background;
    }
    
    /**
     * Create default foreground (transparent)
     */
    private static BufferedImage createDefaultForeground() {
        BufferedImage foreground = new BufferedImage(72, 72, BufferedImage.TYPE_INT_ARGB);
        Graphics2D g2d = foreground.createGraphics();
        
        try {
            setupHighQualityRendering(g2d);
            g2d.setComposite(AlphaComposite.Clear);
            g2d.fillRect(0, 0, 72, 72);
        } finally {
            g2d.dispose();
        }
        
        return foreground;
    }
    
    /**
     * Save image with optimized compression
     */
    public static void saveOptimizedImage(BufferedImage image, File outputFile) throws IOException {
        javax.imageio.ImageWriter writer = javax.imageio.ImageIO.getImageWritersByFormatName("PNG").next();
        javax.imageio.ImageWriteParam param = writer.getDefaultWriteParam();
        
        if (param.canWriteCompressed()) {
            param.setCompressionMode(javax.imageio.ImageWriteParam.MODE_EXPLICIT);
            param.setCompressionQuality(0.9f); // High quality compression
        }
        
        try (javax.imageio.stream.ImageOutputStream output = javax.imageio.ImageIO.createImageOutputStream(outputFile)) {
            writer.setOutput(output);
            writer.write(null, new javax.imageio.IIOImage(image, null, null), param);
        } finally {
            writer.dispose();
        }
    }
}
